#include "QXmlModelHandler.h"

QXmlModelHandler::QXmlModelHandler(void)
{
    xMax = 395;
    yMax = 295;
}
bool QXmlModelHandler::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs)
{
    if (name == "NODE")
    {
        int id = -1;
        bool isfixed = false;
        double posx = -1;
        double posy = -1;
        double velx = 0;
        double vely = 0;

        for (int i=0; i<attrs.count(); ++i)
        {
            if (attrs.localName(i) == "id") id = attrs.value(i).toInt();
            if (attrs.localName(i) == "is-fixed") isfixed = attrs.value(i).toInt();
            if (attrs.localName(i) == "pos-x") posx = attrs.value(i).toDouble();
            if (attrs.localName(i) == "pos-y") posy = attrs.value(i).toDouble();
            if (attrs.localName(i) == "vel-x") velx = attrs.value(i).toDouble();
            if (attrs.localName(i) == "vel-y") vely = attrs.value(i).toDouble();
        }
        if ((id>=0)&&(posx>=0)&&(posy>=0))
        {
            if (xMax<posx) xMax = posx;
            if (yMax<posy) yMax = posy;
            QNode *node = new QNode;
            node->setID(id);
            node->setFixed(isfixed);
            node->setPos(QPointF(posx, posy));
            node->setPosDot(QPointF(velx, vely));
            nList << node;
        }
    }

    if (name == "MUSCLE")
    {
        int id = -1;
        int type = -1;
        int node1id = -1;
        int node2id = -1;
        double defL = 0;
        double k = -1;

        for (int i=0; i<attrs.count(); ++i)
        {
            if (attrs.localName(i) == "id") id = attrs.value(i).toInt();
            if (attrs.localName(i) == "type") type = attrs.value(i).toInt();
            if (attrs.localName(i) == "node1-id") node1id = attrs.value(i).toInt();
            if (attrs.localName(i) == "node2-id") node2id = attrs.value(i).toInt();
            if (attrs.localName(i) == "def-l") defL = attrs.value(i).toDouble();
            if (attrs.localName(i) == "k") k = attrs.value(i).toDouble();
        }
        if ((id>=0)&&(node1id>=0)&&(node2id>=0)&&(node1id!=node2id)&&(defL>0)&&(k>=0))
        {
            QAbstractMuscle *muscle;
            switch(type)
            {
            case 1:
                muscle = new QSpongeMuscle;
                break;
            case 2:
                muscle = new QPotentialMuscle;
                break;
            }

            muscle->setID(id);
            muscle->setDefL(defL);
            muscle->setK(k);
            for (int i=0; i<nList.length(); ++i)
            {
                if ((nList[i]->getID()==node1id)||(nList[i]->getID()==node2id)) muscle->addNode(nList[i]);
            }
            mList << muscle;
        }
    }
    if (name == "NERVE")
    {
        int id = -1;
        int type = -1;
        bool curvevis = 0;
        bool issender = 0;
        QString receiverlist;
        double posx = 0;
        double posy = 0;
        double receptorpot = 0;
        bool receptorswitchedon = 0;
        double resistance = 0;
        double relaxtime = 0;

        for (int i=0; i<attrs.count(); ++i)
        {
            if (attrs.localName(i) == "id") id = attrs.value(i).toInt();
            if (attrs.localName(i) == "type") type = attrs.value(i).toInt();
            if (attrs.localName(i) == "curve-vis") curvevis = attrs.value(i).toInt();
            if (attrs.localName(i) == "is-sender") issender = attrs.value(i).toInt();
            if (attrs.localName(i) == "receiver-list") receiverlist = attrs.value(i);
            if (attrs.localName(i) == "pos-x") posx = attrs.value(i).toDouble();
            if (attrs.localName(i) == "pos-y") posy = attrs.value(i).toDouble();
            if (attrs.localName(i) == "receptor-pot") receptorpot = attrs.value(i).toDouble();
            if (attrs.localName(i) == "receptor-switched-on") receptorswitchedon = attrs.value(i).toInt();
            if (attrs.localName(i) == "resistance") resistance = attrs.value(i).toDouble();
            if (attrs.localName(i) == "relax-time") relaxtime = attrs.value(i).toDouble();
        }

        QStringList list = receiverlist.split(";", QString::SkipEmptyParts);
        QList<int> recIntList;
        for (int i=0; i<list.length(); ++i)
        {
            recIntList << list[i].toInt();
        }

        if (type&&(id>=0))
        {
            QNeuron *neuron = new QNeuron;
            QReceptor *receptor = new QReceptor;
            QTransmitter *transmitter = new QTransmitter;
            QElectricSynapse *electricSynapse = new QElectricSynapse;
            QInhibitorSynapse *inhibitorSynapse = new QInhibitorSynapse;
            QChemicalSynapse *chemicalSynapse = new QChemicalSynapse;

            switch (type)
            {
            case 1:
                neuron->setID(id);
                neuron->toggleCurveVisible(curvevis);
                neuron->toggleIsSender(issender);
                neuron->setPos(QPointF(posx, posy));
                neuron->setReceiverIDList(recIntList);
                if (nList.length()>0) nList.last()->addNerve(neuron);
                else nerveList << neuron;
                break;
            case 2:
                receptor->setID(id);
                receptor->toggleCurveVisible(curvevis);
                receptor->setMemPot(receptorpot);
                receptor->toggleIsSender(issender);
                receptor->setPos(QPointF(posx, posy));
                receptor->setReceiverIDList(recIntList);
                if (receptorswitchedon) receptor->switchMode();
                if (nList.length()>0) nList.last()->addNerve(receptor);
                else nerveList << receptor;
                break;
            case 3:
                transmitter->setID(id);
                transmitter->toggleCurveVisible(curvevis);
                transmitter->toggleIsSender(issender);
                transmitter->setPos(QPointF(posx, posy));
                transmitter->setReceiverIDList(recIntList);
                if (nList.length()>0) nList.last()->addNerve(transmitter);
                else nerveList << transmitter;
                break;
            case 4:
                electricSynapse->setID(id);
                electricSynapse->toggleCurveVisible(curvevis);
                electricSynapse->setMultiplier(resistance);
                electricSynapse->toggleIsSender(issender);
                electricSynapse->setReceiverIDList(recIntList);
                if (nList.length()>0) nList.last()->addNerve(electricSynapse);
                else nerveList << electricSynapse;
                break;
            case 5:
                inhibitorSynapse->setID(id);
                inhibitorSynapse->toggleCurveVisible(curvevis);
                inhibitorSynapse->setRelaxTime(relaxtime);
                inhibitorSynapse->toggleIsSender(issender);
                inhibitorSynapse->setReceiverIDList(recIntList);
                if (nList.length()>0) nList.last()->addNerve(inhibitorSynapse);
                else nerveList << inhibitorSynapse;
                break;
            case 6:
                chemicalSynapse->setID(id);
                chemicalSynapse->toggleCurveVisible(curvevis);
                chemicalSynapse->setRelaxTime(relaxtime);
                chemicalSynapse->toggleIsSender(issender);
                chemicalSynapse->setReceiverIDList(recIntList);
                if (nList.length()>0) nList.last()->addNerve(chemicalSynapse);
                else nerveList << chemicalSynapse;
                break;
            }
        }

    }
    if (name == "CONNECTION")
    {
        int senderid = -1;
        int senderchannel = -1;
        int receiverid = -1;

        for (int i=0; i<attrs.count(); ++i)
        {
            if (attrs.localName(i) == "sender-id") senderid = attrs.value(i).toInt();
            if (attrs.localName(i) == "sender-channel") senderchannel = attrs.value(i).toInt();
            if (attrs.localName(i) == "receiver-id") receiverid = attrs.value(i).toInt();
        }

        if ((senderid>=0)&&(senderchannel>=0)&&(receiverid>=0))
        {
            CONNECTION connection;
            connection.sender = nList[senderid];
            connection.senderChannel = senderchannel;
            connection.receiver = mList[receiverid];
            connectionList << connection;
        }
    }
    return true;
}
QList <QNode*> QXmlModelHandler::getNList(void)
{
    for (int i=0; i<nList.length(); ++i)
    {
        for (int j=0; j<nList[i]->getNerveList().length(); ++j)
        {
            for (int k=0; k<nList[i]->getNerveList()[j]->getReceiverIDList().length(); ++k)
            {
                nList[i]->getNerveList()[j]->addReceiver(nList[i]->getNerveList()[nList[i]->getNerveList()[j]->getReceiverIDList()[k]]);
            }
        }
    }

    return nList;
}
QList <QAbstractMuscle*> QXmlModelHandler::getMList(void)
{
    return mList;
}
QList <QNerveTissue*> QXmlModelHandler::getNerveList(void)
{
    for (int i=0; i<nerveList.length(); ++i)
    {
        for (int j=0; j<nerveList[i]->getReceiverIDList().length(); ++j)
        {
            nerveList[i]->addReceiver(nerveList[nerveList[i]->getReceiverIDList()[j]]);
        }
    }

    return nerveList;
}
QList <CONNECTION> QXmlModelHandler::getConnectionList(void)
{
    return connectionList;
}
double QXmlModelHandler::getXSize(void)
{
    return (xMax+5);
}
double QXmlModelHandler::getYSize(void)
{
    return (yMax+5);
}
